package com.glsc.ngateway.platform.service.itflow.flowstrategy.systemNameApply.taskPostHandler;

import com.alibaba.excel.util.CollectionUtils;
import com.glsc.ngateway.common.api.shortmsg.bo.MessageGenericVo;
import com.glsc.ngateway.common.api.shortmsg.feign.IFeignShortmsgService;
import com.glsc.ngateway.common.api.common.enums.Constant;
import com.glsc.ngateway.common.base.domain.mysql.gateway.other.SystemConfig;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.User;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.FlowFormSystemNameApply;
import com.glsc.ngateway.common.base.domain.mysql.gateway.system.SystemMain;
import com.glsc.ngateway.common.api.flowable.dto.CurrentTaskInfoDto;
import com.glsc.ngateway.common.api.flowable.dto.task.doTaskParam.system.SystemPassParamDto;
import com.glsc.ngateway.common.api.flowable.dto.task.doTaskParam.system.SystemRejectParamDto;
import com.glsc.ngateway.common.api.flowable.dto.task.formData.system.SystemNameApplyTaskFormDataDto;
import com.glsc.ngateway.common.api.flowable.dto.task.formData.system.domainDto.FlowFormSystemNameApplyDto;
import com.glsc.ngateway.common.api.flowable.resp.ResponseSituationDto;
import com.glsc.ngateway.common.base.enums.itflow.ITFlowStatus;
import com.glsc.ngateway.common.base.enums.itflow.ITFlowTaskRoleEnum;
import com.glsc.ngateway.common.base.exception.PlatformException;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.FlowFormSystemNameApplyRepo;
import com.glsc.ngateway.platform.service.*;
import com.glsc.ngateway.platform.service.itflow.flowstrategy.AbstractHandlerHelper;
import com.glsc.ngateway.platform.service.owncloud.OwnCloudService;
import com.glsc.ngateway.platform.service.system.SystemMainService;
import com.netflix.discovery.shared.Pair;
import io.jsonwebtoken.lang.Collections;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 设备申领节点辅助类
 *
 * @author xuchang
 */
@Component
public class SNAStepHandlerHelper extends AbstractHandlerHelper {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private SNAStepHandlerHelper handlerHelper;
    @Autowired
    private FlowFormSystemNameApplyRepo systemNameApplyRepo;
    @Autowired
    private FlowCommonService flowCommonService;
    @Autowired
    private SystemMainService systemMainService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private MailService mailService;
    @Autowired
    private UserService userService;
    @Resource
    private OwnCloudService ownCloudService;
    @Resource
    private IFeignShortmsgService iFeignShortmsgService;
    @Resource
    private SystemConfigService systemConfigService;
    @Value("${wechat.url}")
    private String weChatUrl;

    protected void endTaskAfterHandle(SystemPassParamDto<FlowFormSystemNameApplyDto, SystemNameApplyTaskFormDataDto> param, String operator) {
        ResponseSituationDto processInfo = flowCommonService.getProcessInfo(param.getProcessId());
        //如果流程还没走完，发送邮件通知给下一个人
        if (!Collections.isEmpty(processInfo.getCurrentTaskInfoDtoList())) {
            FlowFormSystemNameApplyDto formMainData = param.getFlowableFormData().getFormMainData();
            this.notify(processInfo, formMainData.getProcessTitle(), formMainData.getFlowCreateOperatorName(), formMainData.getOpName());
        } else {
//            //抄送给系统名称管理员
//            List<String> accountList = roleService.getUsersByRole(ITFlowTaskRoleEnum.ROLE_SYSTEM_NAME_ADMIN.getRoleName());
//            if (Collections.isEmpty(accountList)) {
//                logger.info("系统名称申请-一级部门负责人审批-抄送:无抄送人");
//            } else {
//                SystemNameApplyTaskFormDataDto data = param.getFlowableFormData();
//                handlerHelper.copyPorcess(param.getProcessId(), operator, accountList
//                        , String.format("【抄送】-【系统名称申请流程】-【%s】", data.getProcessTitle())
//                        , AbstractHandlerHelper.GATEWAY_IT_FLOW_URL + "systemNameFlowAudit?flowProcessId=" + param.getProcessId()
//                        , String.format("申请人：" + data.getFormMainData().getFlowCreateOperatorName() +
//                                "<br/>  申请系统名称：" + data.getFormMainData().getOpName() +
//                                "<br/>  请知悉。可至国联技术服务平台内查阅相关事宜。"));
//            }
        }
    }

    /**
     * 发送邮件通知
     */
    public void notify(@NotNull ResponseSituationDto processInfo, String processTitle, String creator, String opName) {
        if (Collections.isEmpty(processInfo.getCurrentTaskInfoDtoList())) {
            logger.info("系统名称申请流程-通知失败：当前无人员可通知");
        } else {
            String title = "【国联技术服务平台提醒】您有新的待办";
            String headTitle = String.format("【待办】-【系统名称申请】-【%s】", processTitle);
            String mailContent = String.format("申请人：" + creator + "<br/>  申请系统名称：" + opName);
            List<Pair<CurrentTaskInfoDto, List<User>>> mailList = processInfo.getCurrentTaskInfoDtoList().stream()
                    .map(t -> new Pair<>(t, userService.findAllByAccountList(t.getCurrentAssigneeList())))
                    .filter(t -> !CollectionUtils.isEmpty(t.second()))
                    .collect(Collectors.toList());
            SystemConfig agentIdConfig = systemConfigService.findByCode("WECHAT_GATEWAY_APP_AGENTID");
            boolean hasAgentIdConfig = Objects.nonNull(agentIdConfig) && Strings.isNotBlank(agentIdConfig.getConfigValue());
            if (Collections.isEmpty(mailList)) {
                logger.info("系统名称变更流程-通知失败：未找到邮箱");
            } else {
                mailList.forEach(p -> {
                    List<String> currentTaskIdList = p.first().getCurrentTaskIdList();
                    Map<String, String> emailMap = p.second().stream().collect(Collectors.toMap(User::getName, User::getEmail));
                    for (int i = 0; i < currentTaskIdList.size(); i++) {
                        String titleLink = AbstractHandlerHelper.GATEWAY_IT_FLOW_URL + "systemNameFlowAudit?flowTaskId=" + currentTaskIdList.get(i);
                        mailService.sendMail(new String[]{emailMap.get(p.second().get(i).getName())}, null, title, titleLink, headTitle,
                                mailContent + "<br/>  请知悉。可至国联技术服务平台内查阅相关事宜。", null, Constant.MAIL_TYPE_IT_FLOW);
                        if (hasAgentIdConfig) {
                            iFeignShortmsgService.sendAgentMessageGeneric(MessageGenericVo.builder()
                                    .oaUserAccounts(List.of(p.second().get(i).getUsername()))
                                    .agentId(agentIdConfig.getConfigValue())
                                    .textContent(title +
                                            "<br><a href='" + weChatUrl + "'>" + headTitle + "</a>" +
                                            "<br>  " + mailContent)
                                    .build());
                        }
                    }
                });
            }

        }
    }

    /**
     * 驳回后置处理方法
     */
    protected void afterHandle(@NotNull SystemRejectParamDto param, @NotNull String operator) {
        List<FlowFormSystemNameApply> formDataList = systemNameApplyRepo.findAllByProcessId(param.getProcessId());
        formDataList.forEach(f -> {
            f.setUpdateAccount(operator);
        });
        systemNameApplyRepo.saveAll(formDataList);
        rejectSendMsg(param, operator, "【待办】-【系统名称申请】-【%s】");
    }

    public void applySysName(Long mainFormId) {
        FlowFormSystemNameApply apply = systemNameApplyRepo.findById(mainFormId)
                .orElseThrow(() -> PlatformException.error(String.format("系统名称申领，消息处理异常：未找到主表数据，%s", mainFormId)));
        //幂等
        if (apply.getIsClose() == 0) {
            //如果已有相同名称系统，直接修改当前信息
            SystemMain systemMain = systemMainService.findByOpName(apply.getOpName());
            if (Objects.isNull(systemMain)) {
                systemMain = new SystemMain();
            }
            systemMain.setOpName(apply.getOpName());
            systemMain.setOpBuild(apply.getOpBuild());
            systemMain.setMainClass(apply.getMainClass());
            systemMain.setSystemClass(apply.getSystemClass());
            systemMain.setBusinessDepartment(StringUtils.isBlank(apply.getBusinessDepartmentArr()) ?
                    java.util.Collections.EMPTY_LIST : Arrays.asList(apply.getBusinessDepartmentArr().split(",")));
            systemMain.setBelongDeptId(apply.getBelongDeptId());
            systemMain.setOpGroupId(StringUtils.isBlank(apply.getOpGroupIdArr()) ?
                    java.util.Collections.EMPTY_LIST : Arrays.asList(apply.getOpGroupIdArr().split(",")));
            systemMain.setMemberManager(StringUtils.isBlank(apply.getMemberManagerArr()) ?
                    java.util.Collections.EMPTY_LIST : Arrays.asList(apply.getMemberManagerArr().split(",")));
            systemMain.setSystemManager(StringUtils.isBlank(apply.getSystemManagerArr()) ?
                    java.util.Collections.EMPTY_LIST : Arrays.asList(apply.getSystemManagerArr().split(",")));
            systemMain.setOpsManager(StringUtils.isBlank(apply.getOpsManagerArr()) ?
                    java.util.Collections.EMPTY_LIST : Arrays.asList(apply.getOpsManagerArr().split(",")));
            systemMain.setOpSupport(apply.getOpSupport());
            systemMain.setSystemSummary(apply.getSystemSummary());
            systemMain.setStatus("1");
            systemMain.setSystemImportance(apply.getSystemImportance());
            systemMainService.addOrUpdate(systemMain, "系统申请流程");
            apply.setIsClose(1);
            apply.setStatus(ITFlowStatus.END.getCode());
            apply.setSystemClassNo(systemMain.getSystemClassNo());
            systemNameApplyRepo.save(apply);
            ownCloudService.matchDir(List.of(systemMain.getOpName()), "【国联技术服务平台】-" + apply.getProcessTitle() + "创建");
        }
    }
}
